package io.renren.modules.customer.controller;

import io.renren.common.CommonConstants;
import io.renren.common.annotation.SysLog;
import io.renren.common.template.excel.ExportResult;
import io.renren.common.utils.ExcelExportUtils;
import io.renren.common.utils.ExcelImportUtil;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.validator.ValidatorUtils;
import io.renren.modules.customer.bean.CustomerExportBean;
import io.renren.modules.customer.entity.CustomerEntity;
import io.renren.modules.customer.service.CustomerService;
import io.renren.modules.customer.service.MessageRequestService;
import io.renren.modules.sys.controller.AbstractController;
import io.renren.modules.sys.service.SysConfigService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.http.entity.ContentType;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 
 *
 * @author Sean
 * @email seanla@qq.com
 * @date 2020-03-17 15:55:41
 */
@RestController
@RequestMapping("/customer/customer")
@Configuration
public class CustomerController extends AbstractController {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerController.class);

    @Autowired
    private CustomerService customerService;

    @Autowired
    private MessageRequestService messageRequestService;

    @Autowired
    private SysConfigService sysConfigService;

    /**
     * 上传文件的临时路径
     */
    @Value("${renren.upload-path}")
    private String uploadPath;

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("customer:customer:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = customerService.queryPage(params);
        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("customer:customer:info")
    public R info(@PathVariable("id") Long id){
		CustomerEntity customer = customerService.getById(id);
        return R.ok().put("customer", customer);
    }

    /**
     * 保存
     */
    @SysLog("新增客户资料")
    @RequestMapping("/save")
    @RequiresPermissions("customer:customer:save")
    public R save(@RequestBody CustomerEntity customer){
        ValidatorUtils.validateEntity(customer);
		customerService.save(customer);
        customer.setCreateUserId(getUserId());
        customer.setCreateTime(new Date());
        return R.ok();
    }

    /**
     * 修改
     */
    @SysLog("修改客户资料")
    @RequestMapping("/update")
    @RequiresPermissions("customer:customer:update")
    public R update(@RequestBody CustomerEntity customer){
        ValidatorUtils.validateEntity(customer);
		customerService.updateById(customer);
        return R.ok();
    }

    /**
     * 删除
     */
    @SysLog("删除客户资料")
    @RequestMapping("/delete")
    @RequiresPermissions("customer:customer:delete")
    public R delete(@RequestBody Long[] ids){
		customerService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }

    /**
     * 上传文件
     */
    @SysLog("批量上传客户资料")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @RequiresPermissions("customer:customer:upload")
    public R upload(@RequestParam("file") MultipartFile file) {
        if (file != null) {
            boolean hasUploadError = false;
            File destFile = null;
            try {
                LOGGER.debug("The upload file name is {}", file.getOriginalFilename());
                String filePath = this.uploadPath + getUserId() + "/" + file.getOriginalFilename();
                destFile = new File(filePath);
                if (destFile.exists()) {
                    hasUploadError = !destFile.delete();
                }
                if (!destFile.getParentFile().exists()) {
                    hasUploadError = !destFile.getParentFile().mkdirs();
                }
                file.transferTo(destFile);
            } catch (Exception e) {
                LOGGER.error("文件上传失败", e);
                hasUploadError = true;
            }

            if (hasUploadError) {
                return R.error("文件上传失败");
            } else {
                //解析文件并获得数据
                List<CustomerExportBean> beans = ExcelImportUtil.importExcel(destFile, CustomerExportBean.class);
                if (beans != null) {
                    List<CustomerExportBean> filtered = beans.stream().filter(b -> {
                        return StringUtils.isNotBlank(b.getMobilePhone()) && StringUtils.isNotBlank(b.getSourceFile()) && StringUtils.isNotBlank(b.getName()) &&
                                StringUtils.isNotBlank(b.getArea()) && StringUtils.isNotBlank(b.getChannel()) && StringUtils.isNotBlank(b.getChannelSource())
                                && StringUtils.isNotBlank(b.getCity()) && StringUtils.isNotBlank(b.getLabel());
                    }).collect(Collectors.toList());
                    if (beans.size() > filtered.size()) {
                        return R.error("数据不完整，请检查文件中的每个字段是否不为空且填写正确");
                    } else {
                        List<CustomerEntity> result = this.customerService.batchUploadCustomerInformation(filtered, getUserId());
                        if (result.size() == filtered.size()) {
                            return R.ok();
                        } else {
                            return R.ok("数据中包含部分已存在的用户，但未存在的数据已保存");
                        }
                    }
                } else {
                    return R.ok("文件中不包含任何数据");
                }
            }
        } else {
            return R.error("上传文件为空");
        }
    }

    /**
     * 下载批量邀请模版
     */
    @RequestMapping(value = "/download-template", method = RequestMethod.GET)
    @RequiresPermissions("customer:customer:upload")
    public void downloadBatchTemplate(HttpServletResponse response) throws IOException {
        LOGGER.debug("execute downloadBatchTemplate method");

        // 执行业务
        ExportResult exportResult = new ExportResult();
        exportResult.setFilePrefix("客户资料导入")
                .setItemDto(CustomerExportBean.class)
                .setBeanList(Collections.emptyList());

        //文件名
        String fileName = ExcelExportUtils.createFileName(exportResult.getFilePrefix());
        response.setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
        response.setHeader("Content-disposition", new String(ExcelExportUtils.excelAttachmentFileHeaderValue(fileName).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1.name()));
        response.flushBuffer();
        //导出操作
        ExcelExportUtils.generateWorkbook(exportResult.getBeanList(), exportResult.getItemDto()).write(response.getOutputStream());
        LOGGER.debug("info downloadBatchTemplate finish");
    }

    /**
     * 发送短信
     */
    @SysLog("批量发送短信")
    @RequestMapping(value = "/messaging", method = RequestMethod.POST)
    @RequiresPermissions("customer:customer:messaging")
    public R messaging(@RequestBody Long[] ids) {
        //检查短信模板配置
        String template = this.sysConfigService.getValue(CommonConstants.PA_SMS_TEMPLATE);
        if (StringUtils.isBlank(template)) {
            return R.error("缺少短信模板配置，请先设置短信模板(参数名=" + CommonConstants.PA_SMS_TEMPLATE +")后再发送短信");
        }
        if (ids != null && ids.length > 0) {
            String uuid = DigestUtils.md5Hex(String.valueOf(getUserId()) + String.valueOf(Thread.currentThread().getId()) + String.valueOf(System.currentTimeMillis() + UUID.randomUUID().toString()));
            String batchNumber = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
            batchNumber += (uuid.substring(0,3) + uuid.substring(uuid.length() - 3)).toUpperCase();
            this.messageRequestService.batchSendMessages(batchNumber, ids, getUserId(), template);
        }
        return R.ok();
    }
}
